package com.taofengsdk.widegt;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.SurfaceTexture;
import android.graphics.drawable.AnimationDrawable;
import android.icu.text.IDNA;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.NonNull;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.taofengsdk.R;
import com.taofengsdk.adutil.LogUtils;
import com.taofengsdk.adutil.Utils;
import com.taofengsdk.constant.SDKConstant;
import com.taofengsdk.video.parameters.AdParameters;

import java.io.IOException;

/**
 * Created by tao on 17-3-14.
 *
 * @function 负责广告播放，暂停，事件触发
 */

public class CustomVideoView extends RelativeLayout implements View.OnClickListener,
        MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,
        MediaPlayer.OnCompletionListener, MediaPlayer.OnBufferingUpdateListener,
        TextureView.SurfaceTextureListener, MediaPlayer.OnInfoListener {

    private Context mContext;
    /**
     * Constant
     */
    private static final String TAG = "MraidVideoView";
    private static final int TIME_MSG = 0x01;
    private static final int TIME_INVAL = 1000;
    private static final int STATE_ERR = -1;
    private static final int STATE_IDLE = 0;
    private static final int STATE_PLAYING = 1;
    private static final int STATE_PAUSE = 2;
    private static final int LOAD_TOTAL_COUNT = 3;
    /**
     * UI
     */
    private ViewGroup mParentContainer;
    private RelativeLayout mPlayView;
    private TextureView mVideoView;
    private Button mMiniPlayBtn;
    private ImageView mFullBtn;
    private ImageView mLoadingBar;
    private ImageView mFrameView;
    private AudioManager mAudioManager;
    private Surface mVideoSurface;
    /**
     * Data
     */
    private String mUrl;
    private String mFrameUrl;
    private boolean mIsMute;
    private int mScreenWidth, mDestationHeight;
    /**
     * State
     */
    public boolean mIsCanPlay = true;
    private boolean mIsRealPause;
    private boolean mIsComplete;
    private int mCurrentCount;
    private int playState = STATE_IDLE;

    private MediaPlayer mMediaPlayer;
    private ADVideoPlayerListener mAdvideoPlayListener;
    private ADFrameImageLoadListener mFrameLoadListener;
    private ScreenEventReceiver mScreenRecevier;


    private Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case TIME_MSG:
                    if (isPlaying()) {
                        //还可以在这里更新progressbar
                        mAdvideoPlayListener.onBufferUpdate(getCurrentPosition());
                        sendEmptyMessageDelayed(TIME_MSG, TIME_INVAL);
                    }
                    break;
            }
        }
    };

    public CustomVideoView(Context context, ViewGroup mParentContainer) {
        super(context);
        this.mContext = context;
        this.mParentContainer = mParentContainer;
        mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);

        initData();
        initView();
        registerBroadcastReceiver();
    }

    private void initData() {
        DisplayMetrics dm = new DisplayMetrics();
        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(dm);
        mScreenWidth = dm.widthPixels;
        mDestationHeight = (int) (mScreenWidth * SDKConstant.VIDEO_HEIGHT_PERCENT);
    }

    private void initView() {
        LayoutInflater inflater = LayoutInflater.from(this.getContext());
        mPlayView = (RelativeLayout) inflater.inflate(R.layout.xadsdk_video_player, this);
        mVideoView = (TextureView) mPlayView.findViewById(R.id.xadsdk_player_video_textureView);

        mVideoView.setOnClickListener(this);
        mVideoView.setKeepScreenOn(true);
        mVideoView.setSurfaceTextureListener(this);

        initSmallLayoutMode();
    }

    //小模式状态
    private void initSmallLayoutMode() {
        mMiniPlayBtn = (Button) mPlayView.findViewById(R.id.xadsdk_small_play_btn);
        mFullBtn = (ImageView) mPlayView.findViewById(R.id.xadsdk_to_full_view);
        mFrameView = (ImageView) mPlayView.findViewById(R.id.framing_view);
        mLoadingBar = (ImageView) mPlayView.findViewById(R.id.loading_bar);

        LayoutParams params = new LayoutParams(mScreenWidth, mDestationHeight);
        params.addRule(RelativeLayout.CENTER_IN_PARENT);
        mPlayView.setLayoutParams(params);

        mMiniPlayBtn.setOnClickListener(this);
        mFullBtn.setOnClickListener(this);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return true;
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {

    }

    @Override
    public void onCompletion(MediaPlayer mp) {

        if (mAdvideoPlayListener != null) {
            mAdvideoPlayListener.onAdVideoLoadComplete();
        }
        playBack();
        setIsComplete(true);
        setIsRealPause(true);
    }

    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        LogUtils.e(TAG, "onVisibilityChanged" + visibility);
        super.onVisibilityChanged(changedView, visibility);

        if (visibility == VISIBLE && playState == STATE_PAUSE) {
            if (isComplete() || isRealPause()) {
                pause();
            } else {
                decideCanPlay();
            }
        } else {
            pause();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        LogUtils.i(TAG, "onDetachedFromWindow");
        super.onDetachedFromWindow();
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        this.playState = STATE_ERR;
        mMediaPlayer = mp;
        if (mMediaPlayer != null) {
            mMediaPlayer.reset();
        }
        if (mCurrentCount >= LOAD_TOTAL_COUNT) {
            showPausView();
            if (mAdvideoPlayListener != null) {
                mAdvideoPlayListener.onAdVideoLoadFailed();
            }
        }
        this.stop();

        return true;
    }


    @Override
    public void onPrepared(MediaPlayer mp) {
        LogUtils.i(TAG, "onPrepared");
        this.mMediaPlayer = mp;
        if (mMediaPlayer != null) {
            mMediaPlayer.setOnBufferingUpdateListener(this);
            mCurrentCount = 0;
            if (mAdvideoPlayListener != null) {
                mAdvideoPlayListener.onAdVideoLoadSuccess();
            }
            //满足自动播放条件，则直接播放
            if (Utils.canAutoPlay(getContext(), AdParameters.getCurrentSetting()) &&
                    Utils.getVisiblePercent(mParentContainer) > SDKConstant.VIDEO_SCREEN_PERCENT) {
                setCurrentPlaySlate(STATE_PAUSE);
                resume();
            } else {
                setCurrentPlaySlate(STATE_PLAYING);
                pause();
            }
        }
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        mVideoSurface = new Surface(surface);
        checkMediaPlayer();
        load();
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }

    public void load() {
        if (this.playState != STATE_IDLE) {
            return;
        }
        LogUtils.d(TAG, "do play url = " + this.mUrl);
        showLoadingView();
        try {
            setIsMute(true);
            mMediaPlayer.setDataSource(this.mUrl);
            setCurrentPlaySlate(STATE_IDLE);
            checkMediaPlayer();
            mMediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
            stop();
        }

    }

    public void pause() {
        if (this.playState != STATE_PLAYING) {
            return;
        }
        LogUtils.d(TAG, "do pause");
        if (isPlaying()) {
            entryPauseState();
            showPausView();
            mMediaPlayer.pause();
            if (!isCanPlay()) {
                mMediaPlayer.seekTo(0);
            }
        }
        mHandler.removeCallbacksAndMessages(null);
    }

    public void resume() {
        if (this.playState != STATE_PAUSE) {
            return;
        }

        LogUtils.d(TAG, "do resume");
        try {
            if (!isPlaying()) {
                entryResumeState();
                showPlayView();
                mMediaPlayer.start();
                mHandler.sendEmptyMessage(TIME_MSG);
            } else {
                showPausView();
            }
        } catch (Exception e) {
            Log.e("TAG", e.getMessage());
        }
    }

    public void stop() {
        LogUtils.d(TAG, " do stop");
        if (this.mMediaPlayer != null) {
            this.mMediaPlayer.reset();
            this.mMediaPlayer.setOnCompletionListener(null);
            this.mMediaPlayer.stop();
            this.mMediaPlayer.release();
            this.mMediaPlayer = null;
        }


        if (mCurrentCount < LOAD_TOTAL_COUNT) {
            mCurrentCount++;
            load();
        } else {
            showPausView();
        }

    }

    public void destory() {
        LogUtils.d(TAG, " do destroy");
        if (this.mMediaPlayer != null) {
            this.mMediaPlayer.setOnSeekCompleteListener(null);
            this.mMediaPlayer.stop();
            this.mMediaPlayer.release();
            this.mMediaPlayer = null;
        }
        setCurrentPlaySlate(STATE_IDLE);
        mCurrentCount = 0;
        setIsComplete(false);
        setIsRealPause(false);
        unRegisterBroadcastReceiver();
        mHandler.removeCallbacksAndMessages(null); //release all message and runnable
        showPausView(); //除了播放和loading外其余任何状态都显示pause
    }

    public void playBack() {
        LogUtils.d(TAG, " do playBack");
        setCurrentPlaySlate(STATE_PAUSE);
        mHandler.removeCallbacksAndMessages(null);
        if (mMediaPlayer != null) {
            mMediaPlayer.setOnCompletionListener(null);
            mMediaPlayer.seekTo(0);
            mMediaPlayer.pause();
        }
        this.showPausView();
    }


    private void showLoadingView() {
        mFrameView.setVisibility(View.GONE);
        mFullBtn.setVisibility(View.GONE);
        mMiniPlayBtn.setVisibility(View.GONE);
        mLoadingBar.setVisibility(View.VISIBLE);
        AnimationDrawable anim = (AnimationDrawable) mLoadingBar.getBackground();
        anim.start();

        loadFrameImage();

    }

    public void loadFrameImage() {
        if (mFrameLoadListener != null) {
            mFrameLoadListener.onStartFrameLoad(this.mFrameUrl, new ImageLoaderListener() {
                @Override
                public void onLoadingComplete(Bitmap loadedImage) {
                    if (loadedImage != null) {
                        mFrameView.setScaleType(ImageView.ScaleType.FIT_XY);
                        mFrameView.setImageBitmap(loadedImage);
                    } else {
                        mFrameView.setScaleType(ImageView.ScaleType.FIT_CENTER);
                        mFrameView.setImageResource(R.drawable.xadsdk_img_error);
                    }
                }
            });
        }
    }

    private void showPausView() {
        mLoadingBar.clearAnimation();
        mLoadingBar.setVisibility(View.GONE);
        mFullBtn.setVisibility(View.VISIBLE);
        mMiniPlayBtn.setVisibility(View.VISIBLE);
        mFrameView.setVisibility(View.VISIBLE);
        setIsMute(false);
        loadFrameImage();
    }

    private void showPlayView() {
        mLoadingBar.clearAnimation();
        setIsMute(true);
        mLoadingBar.setVisibility(View.GONE);
        mMiniPlayBtn.setVisibility(View.GONE);
        mFrameView.setVisibility(View.GONE);
        mFullBtn.setVisibility(View.VISIBLE);

    }

    /**
     * 是否禁音
     *
     * @param isMute
     */
    public void setIsMute(boolean isMute) {
        LogUtils.d(TAG, "mute");
        this.mIsMute = isMute;
//        if (mMediaPlayer != null && this.mAudioManager != null) {
//            float volume = isMute ? 0.0f : 1.0f;
//            mMediaPlayer.setVolume(volume, volume);
//        }
    }

    private void setCurrentPlaySlate(int slate) {
        this.playState = slate;
    }

    public void setIsRealPause(boolean isPause) {
        this.mIsRealPause = isPause;
    }

    public void setIsComplete(boolean isComplete) {
        this.mIsComplete = isComplete;
    }

    public void setIsCanPlay(boolean isCanPlay) {
        this.mIsCanPlay = isCanPlay;
    }

    public void isShowFullBtn(boolean isShow) {
        mFullBtn.setImageResource(isShow ? R.drawable.xadsdk_ad_mini : R.drawable.xadsdk_ad_mini_null);
        mFullBtn.setVisibility(isShow ? View.VISIBLE : View.GONE);
    }

    public boolean isCanPlay() {
        return mIsCanPlay;
    }

    public boolean isRealPause() {
        return mIsRealPause;
    }

    public boolean isComplete() {
        return mIsComplete;
    }

    public boolean isPlaying() {
        if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
            return true;
        }
        return false;
    }

    public boolean isFrameHidden() {
        return mFrameView.getVisibility() == View.VISIBLE ? false : true;
    }

    public void setAdvideoPlayListener(ADVideoPlayerListener playerListener) {
        this.mAdvideoPlayListener = playerListener;
    }

    public void setFrameLoadListener(ADFrameImageLoadListener loadListener) {
        this.mFrameLoadListener = loadListener;
    }

    public void setDataSource(String mUrl) {
        this.mUrl = mUrl;
    }

    public void setFrameURI(String url) {
        mFrameUrl = url;
    }

    private void registerBroadcastReceiver() {
        if (mScreenRecevier == null) {
            mScreenRecevier = new ScreenEventReceiver();
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            filter.addAction(Intent.ACTION_USER_PRESENT);
            getContext().registerReceiver(mScreenRecevier, filter);
        }
    }

    public void unRegisterBroadcastReceiver() {
        if (mScreenRecevier != null) {
            getContext().unregisterReceiver(mScreenRecevier);
        }
    }

    private void checkMediaPlayer() {
        if (mMediaPlayer == null) {
            mMediaPlayer = createMediaPlayer();
        } else {
            mMediaPlayer.setSurface(mVideoSurface);
        }
    }

    private MediaPlayer createMediaPlayer() {
        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.reset();
        mMediaPlayer.setOnPreparedListener(this);
        mMediaPlayer.setOnCompletionListener(this);
        mMediaPlayer.setOnErrorListener(this);
        mMediaPlayer.setOnInfoListener(this);
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        if (mVideoSurface != null && mVideoSurface.isValid()) {
            mMediaPlayer.setSurface(mVideoSurface);
        } else {
            stop();
        }

        return mMediaPlayer;
    }

    private void decideCanPlay() {
        if (Utils.canAutoPlay(getContext(), AdParameters.getCurrentSetting()) &&
                Utils.getVisiblePercent(mParentContainer) > SDKConstant.VIDEO_SCREEN_PERCENT) {
            //来回切换页面时，只有 >50,且满足自动播放条件才自动播放
            resume();
        } else {
            pause();
        }
    }

    public int getCurrentPosition() {
        if (this.mMediaPlayer != null) {
            return mMediaPlayer.getCurrentPosition();
        }
        return 0;
    }

    public int getDuration() {
        if (this.mMediaPlayer != null) {
            return mMediaPlayer.getDuration();
        }
        return 0;
    }

    /**
     * 跳转到指定点并停止
     */
    public void seekAndPause(int position) {
        if (this.playState != STATE_PLAYING) {
            return;
        }

        showPausView();
        if (mMediaPlayer != null) {
            if (isPlaying()) {
                entryPauseState();
                mMediaPlayer.seekTo(position);
                mMediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
                    @Override
                    public void onSeekComplete(MediaPlayer mp) {
                        LogUtils.d(TAG, "do seek and pause");
                        mMediaPlayer.pause();
                        mHandler.removeCallbacksAndMessages(null);
                    }
                });
            }
        }
    }

    /**
     * 跳转指定位置并播放
     *
     * @param position
     */
    public void seekAndResume(int position) {
        if (this.playState != STATE_PAUSE) {
            return;
        }

        showPlayView();
        if (mMediaPlayer != null) {
            entryResumeState();
            mMediaPlayer.seekTo(position);
            mMediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
                @Override
                public void onSeekComplete(MediaPlayer mp) {
                    LogUtils.d(TAG, "do seek and resume");
                    mMediaPlayer.start();
                    mHandler.sendEmptyMessage(TIME_MSG);
                }
            });
        }
    }

    /**
     * 进入播放状态时的状态更新
     */
    private void entryResumeState() {
        setCurrentPlaySlate(STATE_PLAYING);
        setIsMute(true);
        setIsCanPlay(true);
        setIsRealPause(false);
        setIsComplete(false);
    }

    private void entryPauseState() {
        setCurrentPlaySlate(STATE_PAUSE);
        setIsMute(false);
    }


    @Override
    public void onClick(View v) {
        if (v == this.mMiniPlayBtn) {
            if (this.playState == STATE_PAUSE) {

                if (Utils.getVisiblePercent(mParentContainer)
                        > SDKConstant.VIDEO_SCREEN_PERCENT) {
                    resume();
                    this.mAdvideoPlayListener.onClickPlay();
                }
            } else {
                load();
            }
        } else if (v == this.mFullBtn) {
            this.mAdvideoPlayListener.onClickFullScreenBtn();
        } else if (v == mVideoView) {
            if (!isPlaying()) {
                resume();
            } else {
                pause();
                setIsRealPause(true);
                setIsComplete(false);
            }
            this.mAdvideoPlayListener.onClickVideo();
        }
    }

    @Override
    public void onFinishTemporaryDetach() {
        super.onFinishTemporaryDetach();
        destory();
    }

    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
        return true;
    }

    /**
     * 与业务逻辑层(VideoAdslot)通信
     */
    public interface ADVideoPlayerListener {
        void onBufferUpdate(int time);

        void onClickFullScreenBtn();

        void onClickVideo();

        void onClickBackBtn();

        void onClickPlay();

        void onAdVideoLoadSuccess();

        void onAdVideoLoadFailed();

        void onAdVideoLoadComplete();
    }

    /**
     * 监听锁屏事件的广播接收器
     */
    private class ScreenEventReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            //主动锁屏时 pause, 主动解锁屏幕时，resume
            switch (intent.getAction()) {
                case Intent.ACTION_USER_PRESENT:
                    if (playState == STATE_PAUSE) {
                        if (mIsRealPause) {
                            pause();
                        } else {
                            decideCanPlay();
                        }
                    }
                    break;
                case Intent.ACTION_SCREEN_OFF:
                    if (playState == STATE_PLAYING) {
                        pause();
                    }
            }
        }
    }

    public interface ADFrameImageLoadListener {

        void onStartFrameLoad(String url, ImageLoaderListener listener);
    }

    public interface ImageLoaderListener {
        /**
         * 如果图片下载不成功，传null
         *
         * @param loadedImage
         */
        void onLoadingComplete(Bitmap loadedImage);
    }
}
